#include "TcpServer.hpp"
#include "comm.hpp"
#include "Translate.hpp"
#include "Daemon.hpp"
#include "log.hpp"
#include <memory>
#include <cctype>
#include <algorithm>

using namespace std;

void Usage(std::string proc)
{
    std::cout << proc << "server_port" << std::endl;
}

Trans::Translate trans;

void Interactive(int sockfd, std::string &out, std::string in)
{
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
    if (n > 0)
    {
        buffer[n] = 0;
        write(sockfd, in.c_str(), in.size());
    }
    else if (n == 0) // read如果返回值是0， 表示读到了文件结尾(对端关闭了连接！)
    {
        lg.LogMessage(Info, "client quit...");
    }
    else
    {
        lg.LogMessage(Warning, "read socket error, errno code:%d, error string: %s", errno, strerror(errno));
    }
}
// 未来的服务器是部署在你的云服务器上的，你怎么知道你的服务在未来在任何一个时刻都是健康的呢？？
// 可以定期（30s）向服务器发送最小服务请求，如果得到的回复，说明我们的服务是正常的。
// 这个机制，我们称之为心跳机制，我们可以问client->服务器，反向的 server->client
void Ping(int sockfd, InetAddr& addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d", addr.PrintDebug().c_str(), "ping", sockfd);
    std::string message;
    Interactive(sockfd, message, "Pong");
    // 一直进行IO
}

void Translate(int sockfd, InetAddr& addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d", addr.PrintDebug().c_str(), "Translate", sockfd);
    std::string word;
    char wordbuf[128];
    int n = read(sockfd, wordbuf, sizeof(wordbuf) - 1);
    if(n > 0) wordbuf[n] = 0;
    std::string chinese = trans.Excute(wordbuf);
    write(sockfd, chinese.c_str(), chinese.size());

    lg.LogMessage(Debug, "%s Translate service, %s->%s", addr.PrintDebug().c_str(), wordbuf, chinese.c_str());
}

//大小写转换，全部改成大写
void Transform(int sockfd, InetAddr& addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d", addr.PrintDebug().c_str(), "Transform", sockfd);
    char message[128];
    int n = read(sockfd, message, sizeof(message) - 1);//要想正确的读，必须结合用户协议
    if(n > 0) message[n] = 0;

    std::string messagebuf = message;
    std::transform(messagebuf.begin(), messagebuf.end(), messagebuf.begin(), [](unsigned char c){
        return std::toupper(c);
    });

    write(sockfd, messagebuf.c_str(), messagebuf.size());
}

void defaultService(int sockfd, InetAddr& addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d", addr.PrintDebug().c_str(), "defaultService", sockfd);
}
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return Usage_Err;
    }
    uint16_t port = stoi(argv[1]);
    daemon(false, false);
    std::unique_ptr<TcpServer> tsvr = make_unique<TcpServer>(port);
    tsvr->RegisterFunc("ping", Ping);
    tsvr->RegisterFunc("translate", Translate);
    tsvr->RegisterFunc("transform", Transform);

    tsvr->Init();

    lg.Enable(ClassFile);

    tsvr->Start();
    return 0;
}